package com.lzw.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author liuzw
 * @date 2024/1/3
 */
@Configuration
public class RabbitConfig {

    /**
     * 需要申明队列
     *
     * @see RabbitConfig#publisherSimpleDemo1()
     * @see RabbitListener#queues()
     */
    public static String PUBLISHER_SIMPLE_DEMO1;
    /**
     * 无需提前申明
     *
     * @see RabbitListener#queuesToDeclare()
     */
    public static String PUBLISHER_SIMPLE_DEMO2;
    /**
     * 死信队列没有消费者
     */
    public static String PUBLISHER_SIMPLE_DEM10 = "PUBLISHER.SIMPLE.DEM10";

    public static String FANOUT2 = "fanout2";
    public static String DIRECT2 = "direct2";
    public static String DIRECT10 = "direct10";
    public static final String DIRECT11 = "dlx.direct";

    @Bean
    public Jackson2JsonMessageConverter converter() {
        Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter();
        //生成消息唯一ID用于判断幂等性。
        //converter.setCreateMessageIds(true);
        return converter;
    }

    /**
     * 提前申明队列结合{@link RabbitListener#queues()}使用
     * 两种方式 publisherSimpleDemo1 OR  publisherSimpleDemo2
     *
     * @return Queue
     */
    @Bean
    public Queue publisherSimpleDemo1() {
        return new Queue(PUBLISHER_SIMPLE_DEMO1);
    }

    @Bean
    public Queue publisherSimpleDemo2() {
        //durable持久化对队列
        return QueueBuilder.durable(PUBLISHER_SIMPLE_DEMO2).build();
    }

    /**
     * 创建死信队列与死信交换机绑定
     *
     * @return publisherSimpleDemo10
     */
    @Bean
    public Queue publisherSimpleDemo10() {
        //durable持久化对队列
        return QueueBuilder.durable(PUBLISHER_SIMPLE_DEM10).withArgument("x-dead-letter-exchange", DIRECT11).build();
    }

    /**
     * 申明fanout交换机
     * 两种方式 fanoutExchange1 OR directExchange
     *
     * @return Exchange
     */
    @Bean
    public FanoutExchange fanoutExchange1() {
        return new FanoutExchange("fanout1");
    }

    @Bean
    public DirectExchange directExchange() {
        return (DirectExchange) ExchangeBuilder.directExchange("direct1").build();
    }

    @Bean
    public DirectExchange directExchange10() {
        return (DirectExchange) ExchangeBuilder.directExchange(DIRECT10).build();
    }

    @Bean
    public DirectExchange directExchange11() {
        return (DirectExchange) ExchangeBuilder.directExchange(DIRECT11).build();
    }

    /**
     * 绑定交换机与队列关系
     * binding1 OR binding2
     *
     * @return Binding
     */
    @Bean
    public Binding binding1(Queue publisherSimpleDemo1, FanoutExchange fanoutExchange1) {
        return BindingBuilder.bind(publisherSimpleDemo1).to(fanoutExchange1);
    }

    /**
     * 死信交换机
     * 消息超时未被消费进入死信交换机然后路由给其后的队列
     *
     * @param publisherSimpleDemo1 Queue
     * @param fanoutExchange1      FanoutExchange
     * @return Binding
     */
    @Bean
    public Binding binding2(Queue publisherSimpleDemo1, FanoutExchange fanoutExchange1) {
        return BindingBuilder.bind(publisherSimpleDemo1).to(fanoutExchange1);
    }

    @Bean
    public Binding binding2() {
        return BindingBuilder.bind(publisherSimpleDemo2()).to(directExchange()).with("sex");
    }

    @Bean
    public Binding binding10() {
        return BindingBuilder.bind(publisherSimpleDemo10()).to(directExchange10()).with("");
    }

    @Value("${publisher.simple.demo1:PUBLISHER.SIMPLE.DEMO1}")
    public void setPublisherSimpleDemo1(String publisherSimpleDemo1) {
        PUBLISHER_SIMPLE_DEMO1 = publisherSimpleDemo1;
    }

    @Value("${publisher.simple.demo2:PUBLISHER.SIMPLE.DEMO2}")
    public void setPublisherSimpleDemo2(String publisherSimpleDemo2) {
        PUBLISHER_SIMPLE_DEMO2 = publisherSimpleDemo2;
    }

}
